package se.cbb.lib;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;

import se.cbb.lib.SequenceFileWriter;

public class ALFScripts {
	private String path;
	private ArrayList<Sequence> sequences;

	public ALFScripts(String path) {
		this.path = path;
	}

	public void readTrees() {
		String path1 = path + "GeneTrees/";
		String path2 = path + "Mapping/";
		String path3 = path + "PrimeTrees/";
		String path4 = path + "Sequences/";
		readSequences();
		generateNewickTrees();
		generateMappingFiles();
		generateSequenceFiles();
		try {			
			File folder = new File(path1);
			File[] listOfFiles = folder.listFiles();

			int size = 0;
			for(int i = 0; i < listOfFiles.length; i++) {
				String name = listOfFiles[i].getName().substring(8);
				name = name.replace(".nwk", "");
				if(size < Integer.parseInt(name))
					size = Integer.parseInt(name);
			}
			String fileName = "GeneTree";
			for(int i = 1; i <= size; i++) {
				BufferedReader bufferedreader;
				String str;
				try {
					bufferedreader = new BufferedReader(new FileReader(path1 + fileName + i + ".nwk"));
					str = bufferedreader.readLine(); 
					bufferedreader.close();
					
					if(!str.equals("")) {
						str = str.replace("[&&NHX:D=N]", "");
						str = str.replace("[&&NHX:D=Y]", "");

						ArrayList<String> map = new ArrayList<String>();
						for(int j = 0; j < str.length(); j++) {
							if(str.charAt(j) == ':') {
								while(str.charAt(j) != ',' && str.charAt(j) != ';' && str.charAt(j) != ')') {
									j++;
								}
								if(str.charAt(j) != ';')
									j++;
							}

							if(str.charAt(j) == ';' || str.charAt(j) == '(')
								continue;
							else {
								String temp = "";
								while(str.charAt(j) != ':') {
									temp = temp + str.charAt(j);
									j++;
								}
								if(temp != "")
									map.add(temp);
								j--;
							}
						}
						for(int j = 0; j < map.size(); j++) {
							String name = map.get(j);
							String first = "G";
							String[] string = name.split("/");
							String second = string[0];
							if(string[1].startsWith("0000"))
								first = first + string[1].substring(string[1].length() - 1);
							else if(string[1].startsWith("000"))
								first = first + string[1].substring(string[1].length() - 2);
							else if(string[1].startsWith("00"))
								first = first + string[1].substring(string[1].length() - 3);
							else if(string[1].startsWith("0"))
								first = first + string[1].substring(string[1].length() - 4);
							else
								first = first + string[1];
							SequenceFileWriter.writeAndAppendLine(path2, fileName + i + ".map", first + "_" + second + "\t" + second);
						}
						
						ArrayList<String> seqhead = new ArrayList<String>();
						for(int j = 0; j < map.size(); j++) {
							String name = map.get(j);
							String first = "G";
							String[] string = name.split("/");
							String second = string[0];
							if(string[1].startsWith("0000"))
								first = first + string[1].substring(string[1].length() - 1);
							else if(string[1].startsWith("000"))
								first = first + string[1].substring(string[1].length() - 2);
							else if(string[1].startsWith("00"))
								first = first + string[1].substring(string[1].length() - 3);
							else if(string[1].startsWith("0"))
								first = first + string[1].substring(string[1].length() - 4);
							else
								first = first + string[1];
							str = str.replace(map.get(j), first + "_" + second);
							seqhead.add(first + "_" + second);
						}
						
						SequenceFileWriter.writeAndAppendLine(path3, fileName + i + ".nwk", str);
						
						for(int j = 0; j < seqhead.size(); j++) {
							for(int k = 0; k < sequences.size(); k++) {
								if(seqhead.get(j).equals(sequences.get(k).getIdentifier())) {
									SequenceFileWriter.writeAndAppendSequenceInFasta(path4, "GeneTree" + i + ".fa", sequences.get(k));
								}
							}
						}
						
						SequenceFileWriter.writeAndAppendString(path, "Gene_clusters.bcl", seqhead.get(0));
						for(int j = 1; j < seqhead.size(); j++) {
							SequenceFileWriter.writeAndAppendString(path, "Gene_clusters.bcl", "\t" + seqhead.get(j));
						}
						SequenceFileWriter.writeAndAppendLine(path, "Gene_clusters.bcl", "");
					}	
					
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
			}
		} catch (Exception e) {
			System.out.println("readTrees failed : " + e.getMessage());
			System.exit(-1);
		}
	}

	public void readSequences() {
		sequences = new ArrayList<Sequence>();
		String path1 = path + "DB/";
		try {			
			File folder = new File(path1);
			File[] listOfFiles = folder.listFiles();
			for(int i = 0; i < listOfFiles.length; i++) {
				SimpleFileIO reader = new SimpleFileIO();
				reader.readSequenceFile(path1, listOfFiles[i].getName());
				ArrayList<Sequence> sequences2 = reader.getSequences();
				for(int j = 0; j < sequences2.size(); j++) {
					String string[] = sequences2.get(j).getIdentifier().split(",");
					sequences.add(new Sequence(string[0], sequences2.get(j).getSequence()));
					
					String[] strArr = string[0].split("_");
					SequenceFileWriter.writeAndAppendLine(path, "UnsortedSynteny.hsf", strArr[1] + "\t" + "1\t" + string[0] + "\t" + string[2].substring(8));
				}
			}
		} catch (Exception e) {
			
		}
		
	}
	
	public void generateMappingFiles() {
		File theDir = new File(path + "Mapping");

		// if the directory does not exist, create it
		if (!theDir.exists()) {
			System.out.println("creating directory: Mapping ... ");
			boolean result = false;

			try{
				theDir.mkdir();
				result = true;
			} catch(SecurityException se){
				//handle it
			}        
			if(result) {    
				System.out.println("DIR created");  
			}
		}
	}

	public void generateNewickTrees() {
		File theDir = new File(path + "PrimeTrees");

		// if the directory does not exist, create it
		if (!theDir.exists()) {
			System.out.println("creating directory: PrimeTrees ... ");
			boolean result = false;

			try{
				theDir.mkdir();
				result = true;
			} catch(SecurityException se){
				//handle it
			}        
			if(result) {    
				System.out.println("DIR created");  
			}
		}
	}

	public void generateSequenceFiles() {
		File theDir = new File(path + "Sequences");

		// if the directory does not exist, create it
		if (!theDir.exists()) {
			System.out.println("creating directory: Sequences ... ");
			boolean result = false;

			try{
				theDir.mkdir();
				result = true;
			} catch(SecurityException se){
				//handle it
			}        
			if(result) {    
				System.out.println("DIR created");  
			}
		}
	}
}
